<?php

namespace Loop;

require_once(PATH_LOOP . 'Class/CCsvFactory.php');
require_once(PATH_LOOP . 'Class/CObjectFactory.php');

require_once(PATH_LOOP . 'Model/CTestObjectA.php');
require_once(PATH_LOOP . 'Model/CTestObjectB.php');
require_once(PATH_LOOP . 'Model/CTestObjectC.php');
require_once(PATH_LOOP . 'Model/CTestObjectD.php');

/**
 * @package		Loop
 * @category	Class
 */
 
class CObjectFactory_Test extends \UnitTestCase
{
	/**
	 *
	 */

	public function setUp()
	{
		// Create objects

		$this->csvFactory = new \Loop\CCsvFactory();	
		$this->objectFactory = new \Loop\CObjectFactory();
	}


	/**
	 *
	 */

	private function getDatas(&$dataObjectA, &$dataObjectB, &$dataObjectC, &$dataObjectD)
	{
		// Create data A

		$dataObjectA[] = array
		(
			'action' => 'action',
			'source' => 'source',
			'id' => 'id',
			'dateOfCreation' => 'dateOfCreation',
			'name' => 'name',
			'objectBId' => 'objectBId',
			'objectCId' => 'objectCId'
		);

		$dataObjectA[] = array
		(
			'action' => 'C',
			'source' => 'test\\\loop',
			'id' => '30',
			'dateOfCreation' => '2010-05-02 00:25:22',
			'name' => 'test object a1',
			'objectBId' => '40',
			'objectCId' => '50'
		);	

		$dataObjectA[] = array
		(
			'action' => 'C',
			'source' => 'test\\\loop',
			'id' => '31',
			'dateOfCreation' => '2010-05-02 00:25:22',
			'name' => 'test object a2',
			'objectBId' => '42',
			'objectCId' => '52'
		);	

		$dataObjectA[] = array
		(
			'action' => 'C',
			'source' => 'test\\\loop',
			'id' => '33',
			'dateOfCreation' => '2010-05-02 00:25:22',
			'name' => 'test object a3',
			'objectBId' => '41',
			'objectCId' => '50'
		);	


		// Create data B

		$dataObjectB[] = array
		(
			'action' => 'action',
			'source' => 'source',
			'id' => 'id',
			'dateOfCreation' => 'dateOfCreation',
			'description' => 'description',
			'name' => 'name'
		);

		$dataObjectB[] = array
		(
			'action' => 'C',
			'source' => 'test\\\loop',
			'id' => '20',
			'dateOfCreation' => '2010-05-02 00:25:22',
			'description' => 'tatatata',
			'name' => 'test object b'
		);	

		$dataObjectB[] = array
		(
			'action' => 'C',
			'source' => 'test\\\loop',
			'id' => '40',
			'dateOfCreation' => '2010-05-02 00:25:22',
			'description' => 'tatatata',
			'name' => 'test object b'
		);		

		$dataObjectB[] = array
		(
			'action' => 'C',
			'source' => 'test\\\loop',
			'id' => '41',
			'dateOfCreation' => '2010-05-02 00:25:22',
			'description' => 'tatatata1',
			'name' => 'test object b1'
		);		

		$dataObjectB[] = array
		(
			'action' => 'C',
			'source' => 'test\\\loop',
			'id' => '42',
			'dateOfCreation' => '2010-05-02 00:25:22',
			'description' => 'tatatata2',
			'name' => 'test object b2'
		);		

		$dataObjectB[] = array
		(
			'action' => 'C',
			'source' => 'test\\\loop',
			'id' => '43',
			'dateOfCreation' => '2010-05-02 00:25:22',
			'description' => 'tatatata3',
			'name' => 'test object b3'
		);								 


		// Create data C

		$dataObjectC[] = array
		(
			'action' => 'action',
			'source' => 'source',
			'id' => 'id',
			'dateOfCreation' => 'dateOfCreation',
			'price' => 'price'
		);

		$dataObjectC[] = array
		(
			'action' => 'C',
			'source' => 'test\\\loop',
			'id' => '50',
			'dateOfCreation' => '2010-05-02 00:25:22',
			'price' => '20',
		);			

		$dataObjectC[] = array
		(
			'action' => 'C',
			'source' => 'test\\\loop',
			'id' => '51',
			'dateOfCreation' => '2010-05-02 00:25:22',
			'price' => '21',
		);			

		$dataObjectC[] = array
		(
			'action' => 'C',
			'source' => 'test\\\loop',
			'id' => '52',
			'dateOfCreation' => '2010-05-02 00:25:22',
			'price' => '22',
		);			

		$dataObjectC[] = array
		(
			'action' => 'C',
			'source' => 'test\\\loop',
			'id' => '53',
			'dateOfCreation' => '2010-05-02 00:25:22',
			'price' => '23',
		);			

		$dataObjectD[] = array
		(
			'action' => 'action',
			'source' => 'source',
			'id' => 'id',
			'dateOfCreation' => 'dateOfCreation',
			'description' => 'description',
			'name' => 'name',
			'price' => 'price'
		);


		// Create data D

		$dataObjectD[] = array
		(
			'action' => 'C',
			'source' => 'test\\\loop',
			'id' => '1',
			'dateOfCreation' => '2010-05-02 00:25:22',
			'description' => 'tictactic',
			'name' => '12345 lol',
			'price' => '20',
		);	

		$dataObjectD[] = array
		(
			'action' => 'C',
			'source' => 'test\\\loop',
			'id' => '2',
			'dateOfCreation' => '2010-05-02 00:25:22',
			'description' => 'soleil soleil',
			'name' => 'testest',
			'price' => '10000',
		);	

		$dataObjectD[] = array
		(
			'action' => 'C',
			'source' => 'test\\\loop',
			'id' => '3',
			'dateOfCreation' => '2010-05-02 00:25:22',
			'description' => 'lalalalalal',
			'name' => 'solfamire',
			'price' => '30',
		);					
	}


	/**
	 *
	 */

	public function testImport()
	{
		// Get datas

		$this->getDatas($dataObjectA, $dataObjectB, $dataObjectC, $dataObjectD);


		// Create the csv files

		$pathToFiles = path
		(
			array
			(
				PATH_APPLICATION,
				'Data',
				'Import',
				EXTENSION_LOOP
			),
			true
		);


		//
		
		$letters = array('A' , 'B', 'C', 'D');


		// For each model, create csv file with datas

		foreach ($letters as $letter)
		{
			$pathToFileCsv = $pathToFiles . 'testObject' . $letter. '.csv';	


			// Open the file

			$handle = $this->csvFactory->open($pathToFileCsv, 'w');


			$name = 'dataObject' . $letter;


			// Set each line

			foreach ($$name as $data) 
			{
				$this->csvFactory->write($handle, $data);
			}


			// Close the file

			$this->csvFactory->close($handle);
		}


		// Create objects

		$testObjectA = new \Loop\CTestObjectA();
		$testObjectB = new \Loop\CTestObjectB();
		$testObjectC = new \Loop\CTestObjectC();
		$testObjectD = new \Loop\CTestObjectD();


		// Test import

		$exeptions = $this->objectFactory->import
		(
			'Greenwich', 
			array 
			(
				EXTENSION_LOOP => array 
				(
					'CTestObjectA',
					'CTestObjectB',
					'CTestObjectC'
				)
			)
		);


		// Find objectA

		$rawObjectsA = $testObjectA->find();


		// Test

		$this->assertEqual(count($rawObjectsA) , 3);


		// Find objectA externalId 30

		$rawObjectsA = $testObjectA->find
		(
			array 
			(
				'conditions' => array
				(
					'externalId' => array(EQUAL, '30')
				)	
			)
		);


		// Test

		$this->assertEqual(count($rawObjectsA) , 1);


		// Load the Object

		$rawObjectA = array_pop($rawObjectsA);

		$testObjectA->loadFromRawObject($rawObjectA);


		// Tests

		$this->assertEqual($testObjectA->getExternalId(), '30');
		$this->assertEqual($testObjectA->getExternalSource(), 'test\loop');
		$this->assertEqual($testObjectA->getExternalTimeOfCreation(), '1272759922');
		$this->assertEqual($testObjectA->getName(), 'test object a1');
		$this->assertEqual($testObjectA->getTestObjectB()->getExternalId() , '40');
		$this->assertEqual($testObjectA->getTestObjectC()->getExternalId() , '50');


		// Find ObjectA externalId 31

		$rawObjectsA = $testObjectA->find
		(
			array 
			(
				'conditions' => array
				(
					'externalId' => array(EQUAL, '31')
				)	
			)
		);

		// Test

		$this->assertEqual(count($rawObjectsA) , 1);


		// Load the Object

		$rawObjectA = array_pop($rawObjectsA);

		$testObjectA->loadFromRawObject($rawObjectA);


		// Tests

		$this->assertEqual($testObjectA->getExternalId(), '31');
		$this->assertEqual($testObjectA->getExternalSource(), 'test\loop');
		$this->assertEqual($testObjectA->getExternalTimeOfCreation(), '1272759922');
		$this->assertEqual($testObjectA->getName(), 'test object a2');
		$this->assertEqual($testObjectA->getTestObjectB()->getExternalId() , '42');
		$this->assertEqual($testObjectA->getTestObjectC()->getExternalId() , '52');		


		// Find objectA externalId 33

		$rawObjectsA = $testObjectA->find
		(
			array 
			(
				'conditions' => array
				(
					'externalId' => array(EQUAL, '33')
				)	
			)
		);


		// Test

		$this->assertEqual(count($rawObjectsA) , 1);
		

		// Load the object

		$rawObjectA = array_pop($rawObjectsA);

		$testObjectA->loadFromRawObject($rawObjectA);

		
		// Tests

		$this->assertEqual($testObjectA->getExternalId(), '33');
		$this->assertEqual($testObjectA->getExternalSource(), 'test\loop');
		$this->assertEqual($testObjectA->getExternalTimeOfCreation(), '1272759922');
		$this->assertEqual($testObjectA->getName(), 'test object a3');
		$this->assertEqual($testObjectA->getTestObjectB()->getExternalId() , '41');
		$this->assertEqual($testObjectA->getTestObjectC()->getExternalId() , '50');				


		// Find object B

		$rawObjectsB = $testObjectB->find();


		// Test

		$this->assertEqual(count($rawObjectsB) , 5);


		// Find objectB with externalId 20

		$rawObjectsB = $testObjectB->find
		(
			array 
			(
				'conditions' => array
				(
					'externalId' => array(EQUAL, '20')
				)	
			)
		);


		// Test

		$this->assertEqual(count($rawObjectsB) , 1);


		// Load the object

		$rawObjectB = array_pop($rawObjectsB);

		$testObjectB->loadFromRawObject($rawObjectB);


		// Tests

		$this->assertEqual($testObjectB->getExternalId(), '20');
		$this->assertEqual($testObjectB->getExternalSource(), 'test\loop');
		$this->assertEqual($testObjectB->getExternalTimeOfCreation(), '1272759922');
		$this->assertEqual($testObjectB->getName(), 'test object b');		
		$this->assertEqual($testObjectB->getDescription(), 'tatatata');	


		// Find objectB with externalId 40

		$rawObjectsB = $testObjectB->find
		(
			array 
			(
				'conditions' => array
				(
					'externalId' => array(EQUAL, '40')
				)	
			)
		);


		// Test

		$this->assertEqual(count($rawObjectsB) , 1);


		// Load the raw object

		$rawObjectB = array_pop($rawObjectsB);

		$testObjectB->loadFromRawObject($rawObjectB);

		
		// Tests

		$this->assertEqual($testObjectB->getExternalId(), '40');
		$this->assertEqual($testObjectB->getExternalSource(), 'test\loop');
		$this->assertEqual($testObjectB->getExternalTimeOfCreation(), '1272759922');
		$this->assertEqual($testObjectB->getName(), 'test object b');		
		$this->assertEqual($testObjectB->getDescription(), 'tatatata');	

		
		// Find objectB with externalId 41

		$rawObjectsB = $testObjectB->find
		(
			array 
			(
				'conditions' => array
				(
					'externalId' => array(EQUAL, '41')
				)	
			)
		);


		// Test

		$this->assertEqual(count($rawObjectsB) , 1);


		// Load the object

		$rawObjectB = array_pop($rawObjectsB);

		$testObjectB->loadFromRawObject($rawObjectB);


		// Tests

		$this->assertEqual($testObjectB->getExternalId(), '41');
		$this->assertEqual($testObjectB->getExternalSource(), 'test\loop');
		$this->assertEqual($testObjectB->getExternalTimeOfCreation(), '1272759922');
		$this->assertEqual($testObjectB->getName(), 'test object b1');		
		$this->assertEqual($testObjectB->getDescription(), 'tatatata1');			

		
		// Find objectB with externalId 42

		$rawObjectsB = $testObjectB->find
		(
			array 
			(
				'conditions' => array
				(
					'externalId' => array(EQUAL, '42')
				)	
			)
		);


		// Test

		$this->assertEqual(count($rawObjectsB) , 1);


		// Load the object

		$rawObjectB = array_pop($rawObjectsB);

		$testObjectB->loadFromRawObject($rawObjectB);


		// Tests

		$this->assertEqual($testObjectB->getExternalId(), '42');
		$this->assertEqual($testObjectB->getExternalSource(), 'test\loop');
		$this->assertEqual($testObjectB->getExternalTimeOfCreation(), '1272759922');
		$this->assertEqual($testObjectB->getName(), 'test object b2');		
		$this->assertEqual($testObjectB->getDescription(), 'tatatata2');	


		// Find objectB with externalId 40

		$rawObjectsB = $testObjectB->find
		(
			array 
			(
				'conditions' => array
				(
					'externalId' => array(EQUAL, '43')
				)	
			)
		);

		
		// Test

		$this->assertEqual(count($rawObjectsB) , 1);


		// Load the object

		$rawObjectB = array_pop($rawObjectsB);

		$testObjectB->loadFromRawObject($rawObjectB);


		// Tests

		$this->assertEqual($testObjectB->getExternalId(), '43');
		$this->assertEqual($testObjectB->getExternalSource(), 'test\loop');
		$this->assertEqual($testObjectB->getExternalTimeOfCreation(), '1272759922');
		$this->assertEqual($testObjectB->getName(), 'test object b3');		
		$this->assertEqual($testObjectB->getDescription(), 'tatatata3');	


		// Find objectC

		$rawObjectsC = $testObjectC->find();


		// Test

		$this->assertEqual(count($rawObjectsC) , 4);


		// Find objectC with externalId 50

		$rawObjectsC = $testObjectC->find
		(
			array 
			(
				'conditions' => array
				(
					'externalId' => array(EQUAL, '50')
				)	
			)
		);


		// Test

		$this->assertEqual(count($rawObjectsC) , 1);


		// Load the object

		$rawObjectC = array_pop($rawObjectsC);

		$testObjectC->loadFromRawObject($rawObjectC);

		
		// Tests

		$this->assertEqual($testObjectC->getExternalId(), '50');
		$this->assertEqual($testObjectC->getExternalSource(), 'test\loop');
		$this->assertEqual($testObjectC->getExternalTimeOfCreation(), '1272759922');
		$this->assertEqual($testObjectC->getPrice(), '20');		


		// Find objectC with the externalId 51

		$rawObjectsC = $testObjectC->find
		(
			array 
			(
				'conditions' => array
				(
					'externalId' => array(EQUAL, '51')
				)	
			)
		);


		// Test

		$this->assertEqual(count($rawObjectsC) , 1);


		// Load the object

		$rawObjectC = array_pop($rawObjectsC);

		$testObjectC->loadFromRawObject($rawObjectC);


		// Tests

		$this->assertEqual($testObjectC->getExternalId(), '51');
		$this->assertEqual($testObjectC->getExternalSource(), 'test\loop');
		$this->assertEqual($testObjectC->getExternalTimeOfCreation(), '1272759922');
		$this->assertEqual($testObjectC->getPrice(), '21');		


		// Find objectC with the externalId 52

		$rawObjectsC = $testObjectC->find
		(
			array 
			(
				'conditions' => array
				(
					'externalId' => array(EQUAL, '52')
				)	
			)
		);


		// Test

		$this->assertEqual(count($rawObjectsC) , 1);


		// Load the object

		$rawObjectC = array_pop($rawObjectsC);

		$testObjectC->loadFromRawObject($rawObjectC);

		
		// Tests

		$this->assertEqual($testObjectC->getExternalId(), '52');
		$this->assertEqual($testObjectC->getExternalSource(), 'test\loop');
		$this->assertEqual($testObjectC->getExternalTimeOfCreation(), '1272759922');
		$this->assertEqual($testObjectC->getPrice(), '22');		


		// Find objectC with the externalId 53

		$rawObjectsC = $testObjectC->find
		(
			array 
			(
				'conditions' => array
				(
					'externalId' => array(EQUAL, '53')
				)	
			)
		);


		// Test

		$this->assertEqual(count($rawObjectsC) , 1);


		// Load the object

		$rawObjectC = array_pop($rawObjectsC);

		$testObjectC->loadFromRawObject($rawObjectC);


		// Tests

		$this->assertEqual($testObjectC->getExternalId(), '53');
		$this->assertEqual($testObjectC->getExternalSource(), 'test\loop');
		$this->assertEqual($testObjectC->getExternalTimeOfCreation(), '1272759922');
		$this->assertEqual($testObjectC->getPrice(), '23');		


		/*****************************************************************************/


		// Test importObject

		$exeptions = $this->objectFactory->importObject('Greenwich', $testObjectD);


		// Find objectsD

		$rawObjectsD = $testObjectD->find();


		// Test

		$this->assertEqual(count($rawObjectsD) , 3);


		// Find objectD with externalId 1

		$rawObjectsD = $testObjectD->find
		(
			array 
			(
				'conditions' => array
				(
					'externalId' => array(EQUAL, '1')
				)	
			)
		);


		// Test

		$this->assertEqual(count($rawObjectsD) , 1);


		// Load the object

		$rawObjectD = array_pop($rawObjectsD);

		$testObjectD->loadFromRawObject($rawObjectD);


		// Tests

		$this->assertEqual($testObjectD->getExternalId(), '1');
		$this->assertEqual($testObjectD->getExternalSource(), 'test\loop');
		$this->assertEqual($testObjectD->getExternalTimeOfCreation(), '1272759922');	
		$this->assertEqual($testObjectD->getDescription(), 'tictactic');
		$this->assertEqual($testObjectD->getName(), '12345 lol');	
		$this->assertEqual($testObjectD->getPrice(), '20');		


		// Find objectD with externalId 2

		$rawObjectsD = $testObjectD->find
		(
			array 
			(
				'conditions' => array
				(
					'externalId' => array(EQUAL, '2')
				)	
			)
		);


		// Test

		$this->assertEqual(count($rawObjectsD) , 1);


		// Load the object

		$rawObjectD = array_pop($rawObjectsD);

		$testObjectD->loadFromRawObject($rawObjectD);


		// Tests

		$this->assertEqual($testObjectD->getExternalId(), '2');
		$this->assertEqual($testObjectD->getExternalSource(), 'test\loop');
		$this->assertEqual($testObjectD->getExternalTimeOfCreation(), '1272759922');	
		$this->assertEqual($testObjectD->getDescription(), 'soleil soleil');
		$this->assertEqual($testObjectD->getName(), 'testest');	
		$this->assertEqual($testObjectD->getPrice(), '10000');				


		// Find objectD with externalId 3

		$rawObjectsD = $testObjectD->find
		(
			array 
			(
				'conditions' => array
				(
					'externalId' => array(EQUAL, '3')
				)	
			)
		);

		// Test

		$this->assertEqual(count($rawObjectsD) , 1);


		// Load the object

		$rawObjectD = array_pop($rawObjectsD);

		$testObjectD->loadFromRawObject($rawObjectD);


		// Tests

		$this->assertEqual($testObjectD->getExternalId(), '3');
		$this->assertEqual($testObjectD->getExternalSource(), 'test\loop');
		$this->assertEqual($testObjectD->getExternalTimeOfCreation(), '1272759922');	
		$this->assertEqual($testObjectD->getDescription(), 'lalalalalal');
		$this->assertEqual($testObjectD->getName(), 'solfamire');	
		$this->assertEqual($testObjectD->getPrice(), '30');							
	}


	/**
	 *
	 */

	public function testExport()
	{
		// Get datas

		$this->getDatas($dataObjectA, $dataObjectB, $dataObjectC, $dataObjectD);


		// Test export

		$exeptions = $this->objectFactory->export
		(
			'Greenwich', 
			array 
			(
				EXTENSION_LOOP => array 
				(
					'CTestObjectA',
					'CTestObjectB',
					'CTestObjectC'
				)
			)
		);


		// Test if the files have been created


		// Define path to csv

		$pathToFiles = path
		(
			array
			(
				PATH_APPLICATION,
				'Data',
				'Export',
				EXTENSION_LOOP
			),
			true
		);


		//
		
		$letters = array('A' , 'B', 'C');


		// For each model, create csv

		foreach ($letters as $letter)
		{
			$pathToFileCsv = $pathToFiles . 'testObject' . $letter. '.csv';	


			// Test

			$this->assertTrue(file_exists($pathToFileCsv));
		}


		// Get the contents of the files A

		$pathToFileCsv = $pathToFiles . 'testObjectA.csv';	


		// Open the file

		$handle = $this->csvFactory->open($pathToFileCsv, 'r');


		// Get the content

		$result = $this->csvFactory->read($handle);


		// Close the file

		$this->csvFactory->close($handle);			


		//

		$difference = array_diff($dataObjectA, $result);


		// Test

		$this->assertEqual($difference, array());


		// Get the contents of the files B

		$pathToFileCsv = $pathToFiles . 'testObjectB.csv';	


		// Open the file

		$handle = $this->csvFactory->open($pathToFileCsv, 'r');


		// Get the content

		$result = $this->csvFactory->read($handle);


		// Close the file

		$this->csvFactory->close($handle);			


		//

		$difference = array_diff($dataObjectB, $result);


		// Test

		$this->assertEqual($difference, array());


		// Get the contents of the files C

		$pathToFileCsv = $pathToFiles . 'testObjectC.csv';	


		// Open the file

		$handle = $this->csvFactory->open($pathToFileCsv, 'r');


		// Get the content

		$result = $this->csvFactory->read($handle);


		// Close the file

		$this->csvFactory->close($handle);			


		//

		$difference = array_diff($dataObjectC, $result);


		// Test

		$this->assertEqual($difference, array());		


		/****************************************************************/


		// TEST export object

		// Create object

		$testObjectD = new \Loop\CTestObjectD();


		// Export object

		$exeptions = $this->objectFactory->exportObject('Greenwich', $testObjectD);


		// Create path to file

		$pathToFileCsv = $pathToFiles . 'testObjectD.csv';	


		// Test

		$this->assertTrue(file_exists($pathToFileCsv));	


		// Get the contents of the csv file

		// Open the file

		$handle = $this->csvFactory->open($pathToFileCsv, 'r');


		// Get the content

		$result = $this->csvFactory->read($handle);


		// Close the file

		$this->csvFactory->close($handle);			


		$difference = array_diff($dataObjectD, $result);


		// Test

		$this->assertEqual($difference, array());			
	}
}

?>